﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKArchUtils.Utils;
using YJKElementFinish.ColumnSurface.Managers;
using YJKLoopSearch;

namespace YJKElementFinish.ColumnSurface.DataDefinition
{
	public class ColumnEdgeLoopInfo
	{
		public FamilyInstance Component
		{
			get
			{
				return this.m_Component;
			}
		}

		public List<Pole2D> EdgeLoop
		{
			get
			{
				return this.m_EdgeLoop;
			}
		}

		public bool IsColumnFace(Curve curve)
		{
			XYZ endPoint = curve.GetEndPoint(0);
			XYZ endPoint2 = curve.GetEndPoint(1);
			foreach (Pole2D pole2D in this.m_EdgeLoop)
			{
				XYZ xyz = null;
				XYZ xyz2 = null;
				if (pole2D.IsArcPole)
				{
					Arc arc = curve as Arc;
					if (!(arc == null))
					{
						XYZ pt = endPoint;
						XYZ pt2 = endPoint2;
						if (!Geometry.IsEqual(arc.Normal, pole2D.Normal))
						{
							pt = endPoint2;
							pt2 = endPoint;
						}
						Geometry.OverlapType overlapType = Geometry.IsOverlapOfTwoArc(ColumnEdgeLoopInfo.To2D(pole2D.StartPoint), ColumnEdgeLoopInfo.To2D(pole2D.EndPoint), ColumnEdgeLoopInfo.To2D(pole2D.Center), ColumnEdgeLoopInfo.To2D(pt), ColumnEdgeLoopInfo.To2D(pt2), ColumnEdgeLoopInfo.To2D(arc.Center), ref xyz, ref xyz2, 1E-09);
						if (overlapType != Geometry.OverlapType._OT_Linked && overlapType != Geometry.OverlapType._OT_None)
						{
							return true;
						}
					}
				}
				else if (!(curve as Line == null))
				{
					Geometry.OverlapType overlapType2 = Geometry.IsOverlapOfTwoLine(ColumnEdgeLoopInfo.To2D(pole2D.StartPoint), ColumnEdgeLoopInfo.To2D(pole2D.EndPoint), ColumnEdgeLoopInfo.To2D(endPoint), ColumnEdgeLoopInfo.To2D(endPoint2), ref xyz, ref xyz2, true, 0.0001);
					if (overlapType2 != Geometry.OverlapType._OT_Linked && overlapType2 != Geometry.OverlapType._OT_None)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static XYZ To2D(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}

		public ColumnEdgeLoopInfo(ColumnEdgeLoopInfo rhs)
		{
			this.m_Component = rhs.m_Component;
			this.m_EdgeLoop = rhs.m_EdgeLoop;
			this.m_ColumnProfileLoopList = rhs.m_ColumnProfileLoopList;
		}

		public ColumnEdgeLoopInfo(FamilyInstance component, List<Pole2D> edgeLoop, List<ProfileInfo> columnProfileLoopList)
		{
			this.m_Component = component;
			this.m_EdgeLoop = edgeLoop;
			this.m_ColumnProfileLoopList = columnProfileLoopList;
		}

		public static ColumnEdgeLoopInfo CreateByColumn(UIApplication UIApp, FamilyInstance column)
		{
			List<ProfileInfo> columnProfileLoopList = new List<ProfileInfo>();
			List<Pole2D> list = new List<Pole2D>();
			foreach (Solid solid in ElementCommon.GetElementSolids(UIApp, column))
			{
				List<Pole2D> solidProfile = ColumnCommon.GetSolidProfile(solid, column.Id, 0.0, ref columnProfileLoopList);
				list.AddRange(solidProfile);
			}
			return new ColumnEdgeLoopInfo(column, list, columnProfileLoopList);
		}

		public bool IsInside(XYZ pt, bool includeEdge = true)
		{
			using (List<ProfileInfo>.Enumerator enumerator = this.m_ColumnProfileLoopList.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.IsInside(pt, false))
					{
						return true;
					}
				}
			}
			return false;
		}

		private FamilyInstance m_Component;

		private List<Pole2D> m_EdgeLoop = new List<Pole2D>();

		private List<ProfileInfo> m_ColumnProfileLoopList = new List<ProfileInfo>();
	}
}
